package org.bendev.ildaplayer;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.content.Context;
import android.content.ContextWrapper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;

public class RemoteBitmap {
	public interface Callback{
		public void onBitmap( Bitmap bm );
		public void onBitmapError( Exception ex );
	}
	
	public static void get( Uri uri, Callback cb ){
		new BitmapTask( uri, cb ).execute();
	}
	
	public static void get( final ContextWrapper cw, final String cacheName, Uri uri, Callback cb ){
		try{
			FileInputStream fis = cw.openFileInput( cacheName );
			Bitmap bm = BitmapFactory.decodeStream( fis );
			try{ fis.close(); }catch( IOException e ){}
			if( bm==null )
				throw new FileNotFoundException();
			cb.onBitmap( bm );
		}catch( FileNotFoundException e ){
			FileOutputStream fos = null;
			try{ fos = cw.openFileOutput( cacheName, Context.MODE_PRIVATE ); }catch( FileNotFoundException ex ){}
			new BitmapTask( uri, cb, fos ).execute();
		}
		
	}
	
	static class BitmapTaskResult{
		final Bitmap bm;
		final Exception ex;
		public BitmapTaskResult( Bitmap bm ){ this( bm, null ); }
		public BitmapTaskResult( Exception ex ){ this( null, ex ); }
		public BitmapTaskResult( Bitmap bm, Exception ex ){ this.bm = bm; this.ex = ex; }
	}
	
	static class BitmapTask extends AsyncTask<Void, Void, BitmapTaskResult>{
		final Uri uri;
		final Callback cb;
		final FileOutputStream fos;
		
		BitmapTask( Uri uri, Callback cb ){
			this( uri, cb, null );
		}
		
		BitmapTask( Uri uri, Callback cb, FileOutputStream fos ){
			this.uri = uri;
			this.cb = cb;
			this.fos = fos;
		}
		
		@Override
		protected BitmapTaskResult doInBackground( Void... params ) {
			try{
				HttpURLConnection conn = (HttpURLConnection) new URL( uri.toString() ).openConnection();
				conn.setConnectTimeout( 2000 );
				Bitmap res = null;
				InputStream is = conn.getInputStream();

				if( fos==null )
					res = BitmapFactory.decodeStream( is );
				else{
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					byte buffer[] = new byte[4096];
					for( int read; (read = is.read( buffer ))>0; ){
						fos.write( buffer, 0, read );
						baos.write( buffer, 0, read );
					}
					fos.close();
					res = BitmapFactory.decodeByteArray( baos.toByteArray(), 0, baos.size() );
				}
				is.close();
				conn.disconnect();
				return new BitmapTaskResult( res );
			}catch( final IOException e ){
				return new BitmapTaskResult( e );
			}
		}
		
		@Override
		protected void onPostExecute( BitmapTaskResult result ){
			if( cb!=null ){
				if( result.bm!=null )
					cb.onBitmap( result.bm );
				else
					cb.onBitmapError( result.ex );
			}
		}
	}
}
